#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##-- G58 -- S06 ------------------------------------------------------------##
__all__ = []

from .. import autostacks
from .. import comparecards as cmp_cards
from .. import formlib as layout
from .. import hint
from .. import pilelib as stack
from .. import quickplayscore as quickplay
from .. import stackfill as fill
from ..forms import (canfield as CanfieldLayout, klondike as KlondikeLayout,
                     fortythieves as FortyThievesLayout,)
from ..gamelib import info as gi, state, game
from ..hint import DefaultHint, CautiousDefaultHint, CautiousHintMethods
from ..packlib import info as cs, place
from ..piles import spider
from ..utillib.misc import kwdefault
from . import gypsy
from . import grandduchess

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper


class BlindPatience_Hint(CautiousHintMethods, DefaultHint):
    SCORE_FLIP = 80000

    def shall_move_pile(self, from_stack, to_stack, pile, rpile):
        """
        shall_move_pile(from_stack:Stack, to_stack:Stack, pile:seq(Card ...),
          rpile:seq(Card ...)) -> bool

        Returns **pile** builds on **to_stack**?

        Augment whether **pile** from **from_stack** builds on **to_stack** to
        calculate for possible play back of **pile** and whether card face-up.
        """
        if not super(BlindPatience_Hint, self).shall_move_pile(from_stack,
                                                       to_stack, pile, rpile):
            return False
        if self._level < 2:
            return any(not card or not card.face_up
                       for card in (to_stack.TOPCARD, rpile[-1:]))
        else:
            return all(not top_card or not top_card.face_up,
                       len(rpile) < len(to_stack.cards))


class Octave_Talon(stack.WasteTalon):

    @property
    def _piles(self):
        """
        _piles -> tup

        :return: deal Game.s.waste and Game.s.xwastes
        :rtype: tuple
        """
        return self.game.s['wastes']

    def can_deal_cards(self):
        """
        can_deal_cards() -> bool

        Check by Game.talon_deal() if pile can deal more cards. Default is
        while there are cards available and not last round.

        :return: deal more cards?
        :rtype: True | False
        """
        return (self.round != self.max_rounds and
                super(Octave_Talon, self).can_deal_cards())

    @state.move_state('deal')
    def deal_cards(self, sound=False):
        """
        deal_cards([sound:bool=False]) -> None

        Deal cards as parent. Upon redeal, deal _xwastes_ as well once.

        :keyword boolean sound: sound fx?

        note:: modified to use num_deal to deal number of card sets as found
          in some solitaire games.
        """
        had_cards = self.cards
        num_cards = super(Octave_Talon, self).deal_cards(sound)
        if had_cards:  # No redeal occurred
            return num_cards
        if self.cards:
            if sound and self.game.can_play_sound:
                self.game._play_sound('deal')
            num_cards = min(len(self.cards), 8)
            for waste in self.piles[:num_cards]:
                if not self.TOPCARD.face_up:
                    self.game.flip(self)
                self.move_pile(1, waste, frames=4, shadow=0)
            self.game._stop_sound()
        return num_cards


class TheSpark_Talon(stack.DealReserveTalon):

    @state.move_state('deal')
    def deal_cards(self, sound=False):
        """
        deal_cards([sound:bool=False]) -> None

        :keyword boolean sound: sound fx?
        """
        ncards = 0
        if self.cards:
            if sound and self.game.self.game.can_play_sound:
                self.game._play_sound('dealwaste')
            for i in range(self.num_deal):
                ncards += self.dealRowAvail(rows=self._piles, frames=4)
        return ncards


class DoubleGoldMine_RowStack(stack.AC_RowStack):
    _BOTTOM_IMAGE_ = 'shade'


class FortyNine_RowStack(stack.GapTopBuildMethod, stack.AC_RowStack):
    pass


class IndianPatience_RowStack(stack.BO_RowStack):

    def cardsBuild(self, from_stack, cards):
        """
        cardsBuild(from_stack:obj, cards:seq) -> bool

        Check if pile can build with cards from from_stack. Addition pile
        may build with any seq while talon gap else when while gap or not 1
        card on from_stack if in _row_ else self.

        :param object from_stack: sending pile
        :param sequence cards: cards from sending pile
        :return: pile accepts ``cards``?
        :rtype: boolean
        """
        if not super(IndianPatience_RowStack, self).cardsBuild(from_stack,
                                                               cards):
            return False
        if not self.game.s['talon'].cards:
            return True
        stack = from_stack if from_stack in self.game.s['rows'] else self
        return not self.cards or len(stack.cards) != 1


class Blind_AC_RowStack(stack.AC_RowStack):

    def cardsBuild(self, from_stack, cards):
        """
        cardsBuild(from_stack:obj, cards:seq) -> bool

        Check if pile can build with cards from from_stack. Addition pile
        may build on close cards.

        :param object from_stack: sending pile
        :param sequence cards: cards from sending pile
        :return: pile accepts ``cards``?
        :rtype: boolean
        """
        if self.cards and not self.TOPCARD.face_up:
            return True
        return super(Blind_AC_RowStack, self).cardsBuild(from_stack, cards)


class FortyThieves(game.Game):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=13, name='Forty Thieves', game_type=(GT.FORTY_THIEVES |
                    GT.POPULAR), decks=2, version='1.03',
                    skill_level=SL.MOSTLY_SKILL, altnames=(
                    'Napoleon at St. Helena', 'Le Cadran'))
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = FortyThievesLayout.FortyThievesLayout
    _talon_ = stack.WasteTalon
    _waste_ = stack.WasteStack
    _foundation_ = stack.SS_Foundation
    _row_ = Wrap(stack.SS_RowStack, max_move=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        kwdefault(kw, rows=10, playcards=12, wastecards=64, texts=True)
        return super(FortyThieves, self)._create_game(**kw)

    def _start(self, rows=4, flip=True, **kw):
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow()
        self.s['talon'].deal_cards()


class BusyAces(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=80, name='Busy Aces', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 12)
        return super(BusyAces, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        super(BusyAces, self)._start(**kw)


class Limited(BusyAces):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 3 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=228, name='Limited', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _start(self, **kw):
        kw.setdefault('rows', 3)
        super(Limited, self)._start(**kw)


class Express(Limited):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [14 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 3 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=506, name='Express', game_type=(GT.FORTY_THIEVES |
                    GT.ORIGINAL), decks=3, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=14, playcards=16, wastecards=96)
        return super(Express, self)._create_game(**kw)


class Carnation(Limited):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [16 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [16 horz NE, no offset]

    _row_
      Pile 16 horz S _foundation_. Init deal 3 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Pile 1 SW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 16 NE. Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=514, name='Carnation', game_type=(GT.FORTY_THIEVES |
                    GT.ORIGINAL), decks=4, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=16, playcards=20, wastecards=120)
        return super(Carnation, self)._create_game(**kw)


class Courtyard(BusyAces):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      by same suit. Play seq. Gap deal 1 card from _waste_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=110, name='Courtyard', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.SS_RowStack

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _talon_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class BigCourtyard(Courtyard):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      by same suit. Play seq. Gap deal 1 card from _waste_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=505, name='Big Courtyard', game_type=(GT.FORTY_THIEVES
                    | GT.ORIGINAL), decks=3, skill_level=SL.BALANCED, altnames=(
                    'Courtyard (3 decks)',), version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, playcards=16, wastecards=96)
        return super(BigCourtyard, self)._create_game(**kw)


class WaningMoon(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [13 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=79, name='Waning Moon', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 13)
        return super(WaningMoon, self)._create_game(**kw)


class Lucas(WaningMoon):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [13 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=125, name='Lucas', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.SS_RowStack


class NapoleonsSquare(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=295, name='Napoleonʼs Square',
                    game_type=GT.FORTY_THIEVES, decks=2,
                    skill_level=SL.BALANCED, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.SS_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 12)
        return super(NapoleonsSquare, self)._create_game(**kw)


class CarreNapoleon(NapoleonsSquare):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card with finish on _foundation_ without replace. Build
      down in rank by same suit. Play top. Base KING.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base ACE. Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (base_rank=KING, max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=411, name='Carre Napoleon', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(stack.SS_RowStack, base_rank=cs.KING, max_move=1)

    def _start(self):
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        self._play_sound('deal')
        for i in range(4):
            self.s['talon'].dealRow()
            for row in self.s['rows']:
                foundation = cmp_cards.groupTakes(self.s['foundations'], row)
                if foundation:
                    self.move(1, row, foundation, frames=4, shadow=0)
        self.s['talon'].deal_cards()

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)


class Josephine(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=462, name='Josephine', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.92fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.SS_RowStack


class MarieRose(Josephine):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 5 open card. Build down in rank
      by same suit. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=493, name='Marie Rose', game_type=GT.FORTY_THIEVES,
                    decks=3, skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, playcards=16, wastecards=96)
        super(MarieRose, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 5)
        super(MarieRose, self)._start(**kw)


class FamousFifty(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 5 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=683, name='Famous Fifty', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        kw.setdefault('rows', 5)
        super(FamousFifty, self)._start(**kw)


class SanJuanHill(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base Ace. Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=529, name='San Juan Hill', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(SanJuanHill, self)._start(**kw)


class Deuces(SanJuanHill):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 card. Build down in rank
      by same suit wrap. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base TWO. Build up in rank by same suit wrap. Play
      top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (mod=13, base_rank=TWO)
    :cvar Stack _row_: stack.SS_RowStack (max_move=1, mod=13)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=109, name='Deuces', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _foundation_ = Wrap(stack.SS_Foundation, mod=13, base_rank=cs.TWO)
    _row_ = Wrap(stack.SS_RowStack, max_move=1, mod=13)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return TWO on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllTwo)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        super(Deuces, self)._start(**kw)


class Corona(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 3 open card. Build down in rank
      by same suit. Play top. Gap deals 1 card from waste.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play none.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=196, name='Corona', game_type=GT.FORTY_THIEVES,
               decks=2, skill_level=SL.BALANCED, version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)

    def _create_game(self, **kw):
        kw.setdefault('rows', 12)
        return super(Corona, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 3)
        super(Corona, self)._start(**kw)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _waste_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class Quadrangle(Corona):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 3 open card. Build down in rank
      by same suit wrap. Play top. Gap deals 1 card from waste.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal 1 base card. Build up in rank by same suit from
      base wrap. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: Vary_SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.SS_RowStack (max_move=1, mod=13)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=195, name='Quadrangle', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _foundation_ = Wrap(stack.Vary_SS_Foundation, max_move=0)
    _row_ = Wrap(stack.SS_RowStack, mod=13, max_move=1)

    def _start(self, **kw):
        super(Quadrangle, self)._start(**kw)
        base_rank = self.s['talon'].TOPCARD['rank']
        self.s['talon'].dealBaseCard(ncards=1, saveinfo=False)
        self._save_stack_caps(self.s['foundations'], base_rank=base_rank)


class FortyAndEight(FortyThieves):
    """
    Finish cards on _foundation_ within 2 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=23, name='Forty and Eight', game_type=(GT.FORTY_THIEVES
                    | GT.KDE), decks=2, redeals=1,
                    skill_level=SL.MOSTLY_SKILL, version='2.90')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, wastecards=72)
        return super(FortyAndEight, self)._create_game(**kw)


class Streets(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by alt color. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=76, name='Streets', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = Wrap(stack.AC_RowStack, max_move=1)


class BigStreets(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by alt color. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=503, name='Big Streets', game_type=(GT.FORTY_THIEVES |
                    GT.ORIGINAL), decks=3, skill_level=SL.MOSTLY_SKILL,
                    altnames=('Streets (3 decks)',), version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, wastecards=96)
        return super(BigStreets, self)._create_game(**kw)


class Maria(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [9 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by alt color. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=73, name='Maria', game_type=GT.FORTY_THIEVES, decks=2,
                    skill_level=SL.BALANCED, altnames=('Maria Luisa',),
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 9)
        return super(Maria, self)._create_game(**kw)


class Emperor(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 card. Build down in rank
      by alt color. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=310, name='Emperor', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        kw.setdefault('flip', False)
        super(Emperor, self)._start(**kw)


class RankAndFile(Emperor):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 card. Build down in rank
      by alt color. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=71, name='Rank and File', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, altnames=('Dress Parade'),
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.AC_RowStack


class TripleLine(Streets):
    """
    Finish cards on _foundation_ within 2 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [12 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 3 open card. Build down in rank
      by alt color. Play seq. Gap deal 1 card from _waste_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play none.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=197, name='Triple Line', game_type=(GT.FORTY_THIEVES |
                    GT.XORIGINAL), decks=2, redeals=1,
                    skill_level=SL.BALANCED,
                    version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)
    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)
    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 12)
        return super(TripleLine, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 3)
        super(TripleLine, self)._start(**kw)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _talon_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class Roosevelt(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [7 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by alt color. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=588, name='Roosevelt', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 7)
        return super(Roosevelt, self)._create_game(**kw)


class RedAndBlack(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      by alt color. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base ACE. Build up in rank by alt color. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.AC_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=126, name='Red and Black', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _foundation_ = stack.AC_Foundation
    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 8)
        return super(RedAndBlack, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        self.s['talon'].dealRow(rows=self.s['foundations'])
        super(RedAndBlack, self)._start(**kw)


class Zebra(RedAndBlack):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      by alt color. Play seq. Gap deal 1 card from _waste_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base ACE. Build up in rank by alt color. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.AC_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=113, name='Zebra', game_type=(GT.FORTY_THIEVES |
                    GT.GNOME), decks=2, redeals=1, skill_level=SL.BALANCED,
                    version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)
    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)
    _row_ = Wrap(stack.AC_RowStack, max_move=1)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _talon_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class NumberTen(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 top 2 open card. Build down in
      rank by alt color. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=70, name='Number Ten', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.AC_RowStack

    def _start(self, rows=4, **kw):
        rows /= 2
        for flip in (False,) * rows + (True,) * (rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow()
        self.s['talon'].deal_cards()


class NumberTwelve(NumberTen):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 4 top 2 open card. Build down in
      rank by alt color. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=504, name='Number Twelve', game_type=(GT.FORTY_THIEVES
                    | GT.ORIGINAL), decks=3, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, wastecards=96)
        return super(NumberTwelve, self)._create_game(**kw)


class Indian(NumberTen):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 3 top 2 open card. Build down in
      rank by alt suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.BO_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=69, name='Indian', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = Wrap(stack.BO_RowStack, max_move=1)

    def _create_game(self, **kw):
        kw.setdefault('wastecards', 74)
        return super(Indian, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 3)
        super(Indian, self)._start(**kw)


class Midshipman(Indian):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [9 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 top 2 open card. Build down in
      rank by alt suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.BO_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=74, name='Midshipman', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 9)
        return super(Midshipman, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 4)
        super(Midshipman, self)._start(**kw)


class Mumbai(Indian):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [13 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 3 top 2 open card. Build down in
      rank by alt suit. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.BO_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=332, name='Mumbai', game_type=GT.FORTY_THIEVES,
                    decks=3, skill_level=SL.MOSTLY_SKILL, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, wastecards=84)
        return super(Mumbai, self)._create_game(**kw)


class IndianPatience(Indian):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 3 top 2 open card. Build down in
      rank by alt suit after _talon_ gap else not when gap or not 1 card on
      _row_ from_stack or _row_. Play top. Gap deal 3 top 2 open card from
      _talon_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: IndianPatience_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=578, name='Indian Patience', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(IndianPatience_RowStack, max_move=1)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _talon_. 1st row closed. 2-3rd open

        *Parameters*:
           stack : Stack
             pile just played
        """
        if stack in self.s['rows'] and not stack.cards:
            talon = self.talon
            for i in range(len(talon.cards[-3:])):
                self.fill(talon, stack, flip=(i > 1 or len(talon.cards) == 1))

class DoubleGoldMine(Streets):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [9 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Build down in rank by alt color. Play top.

    _talon_
      Deal 3 card on _waste_.

    _waste_
      Init deal 3 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: DoubleGoldMine (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=573, name='Double Gold Mine', game_type=(GT.NUMERICA |
                    GT.ORIGINAL), decks=2, version='0.93fc',
                    skill_level=SL.MOSTLY_SKILL, altnames=(
                    'Gold Mine (2 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, num_deal=3)
    _row_ = DoubleGoldMine_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 9)
        return super(DoubleGoldMine, self)._create_game(**kw)

    def _start(self, **lkw):
        self._play_sound('deal')
        self.s['talon'].deal_cards()


class NapoleonsExile(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      alone. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=198, name='Napoleonʼs Exile',
                    game_type=(GT.FORTY_THIEVES | GT.XORIGINAL), decks=2,
                    skill_level=SL.BALANCED, version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = Wrap(stack.RK_RowStack, max_move=1)


class DoubleRail(NapoleonsExile):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [5 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      alone. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=131, name='Double Rail', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED,
                    version='3.20')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.RK_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 5)
        return super(DoubleRail, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        super(DoubleRail, self)._start(**kw)


class SingleRail(DoubleRail):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [4 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      alone. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=199, name='Single Rail', game_type=GT.FORTY_THIEVES,
                    decks=1, skill_level=SL.MOSTLY_LUCK, version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=4, wastecards=48)
        return super(SingleRail, self)._create_game(**kw)


class FinalBattle(DoubleRail):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [6 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      alone. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=528, name='Final Battle', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 6)
        return super(FinalBattle, self)._create_game(**kw)


class Octave(Streets):
    """
    Finish cards on _foundation_ except court on _row_ within 2 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.OctaveLayout
        - row [8 horz S reserve and foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E talon, no offset]
        - x-waste [1 7 SE, no offset]
        - foundation [8 horz N, no offset]

    _row_
      Init deal 1 open card. Build down in rank
      alone. Play top.

    _talon_
      Deal 1 card on 1st x-waste. After redeal, deal 1 card
      on all x-waste. Last round auto deal all x-waste gap.

    _waste_
      Init deal 1 card. Build none. Play top.
      Pile 7 E. Build none. Play top.

    _foundation_
      Pile 8 N. Init deal base ACE. Build up in rank by same suit. Play top.
      Max 10 cards.
    ------
    :cvar Stack _talon_: Octave_Talon
    :cvar Stack _waste_: grandduchess.ReserveWaste
    :cvar Stack _xwaste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_cards=10)
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=323, name='Octave', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = FortyThievesLayout.OctaveLayout
    _talon_ = Octave_Talon
    _wastes_ = (stack.WasteStack, grandduchess.ReserveWaste)
    _foundation_ = Wrap(stack.SS_Foundation, max_cards=10)

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, xwastes=7, playcards=12)
        return super(Octave, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        kw.setdefault('rows', 3)
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(Octave, self)._start(**kw)

    @property
    def is_complete(self):
        return all(all(s.is_filled for s in self.s['foundations']),
                   not any(s.cards for s in self.s['wastes']))

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _waste_ or _xwastes_ when gap from _talon_ on last round

        *Parameters*:
          stack : Stack
            pile just played
        """
        if self.s['talon'].round == self.s['talon'].max_rounds:
            fill.fromTalon(self, stack, self.s['wastes'])


class FortunesFavor(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.klondike.KlondikeLayout
        - row [12 over 2 row S foundation, vert offset]
        - talon [1 NW, no offset]
        - waste [1 E, no offset]
        - foundation [4 horz N, no offset]
    _row_
      Init deal 1 open card. Build down in
      rank by same suit. Play top. Gap deal 1 card from _waste_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base ACE. Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=416, name='Fortuneʼs Favor', game_type=GT.FORTY_THIEVES,
                    decks=1, skill_level=SL.LUCK, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = KlondikeLayout.KlondikeLayout

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, ncols=2, playcards=0)
        return super(Octave, self)._create_game(**kw), self.s

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(FortunesFavor, self)._start(**kw)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _waste_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class Octagon(FortyThieves):
    """
    Finish cards on _foundation_ within 4 turn.

    _row_
      Pile 4 NW NE SE SW. Init deal 5 open card. Build down in rank
      by same suit. Play top. Gap deal 1 card from _waste_.

    _talon_
      Pile 1 center. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 8 with 2 N E S W. Init deal base ACE. Build up in rank by same
      suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=4)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=426, name='Octagon', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=3, skill_level=SL.BALANCED,
                    version='0.91fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=4)

    def _create_game(self, playcards=12):
        l, s = layout.Layout(self), self.s
        ddx = l._get_stack_width(playcards, l.XS)
        ddy = 3 * l.HYS
        self.table_size = (l.XM + 2 * ddx, l.YM + 4 * l.YS,)
        for y in (l.YM, self.height - l.YS):
            for x in l.row_iter(l.XM, 2, dx=ddx + 2 * l.XS + l.XM):
                s['rows'].append(self._row_(x, y, game=self,
                                         offset=(l.XOFFSET, 0)))
        suits = l.SUITS[:2], l.SUITS[2:6], l.SUITS[6:]
        for y, rsuit in zip(l.col_iter(l.YM, len(suits), ddy), suits):
            row = []
            if len(rsuit) == 2:
                row.extend(l.row_iter(l.XM + ddx, 2))
            else:
                row.extend(l.row_iter(s['size'][0] - 2 * l.XS, 2))
                row.extend(l.row_iter(l.XM, 2))
            for x, suit in zip(row, rsuit):
                s['foundations'].append(self._foundation_(x, y, game=self,
                                     suit=suit))
        x, y = l.XM + ddx, l.YM + ddy
        s['talon'] = self._talon_(x, y, game=self)
        l.set_ncards_text(s['talon'], 's')
        l.set_rounds_text(s['talon'], 'nn')
        x += l.XS
        s['wastes'].append(self._waste_(x, y, game=self))
        l.set_ncards_text(s['wastes'][-1], 's')
        l.defaultStackGroups()
        return l

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        kw.setdefault('rows', 5)
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(FortunesFavor, self)._start(**kw)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _talon_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class Squadron(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.canfield.CanfieldLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 NW, no offset]
        - waste [1 E, no offset]
        - reserve [3 vert S talon, no offset]
        - foundation [8 horz N, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      by same suit. Play top.

    _reserve_
      Init deal 1 card. Build none. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.SS_ReserveStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=440, name='Squadron', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.91fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = CanfieldLayout.CanfieldLayout
    _reserve_ = stack.ReserveStack

    def _create_game(self, **kw):
        kwdefault(kw, reserves=3, playcards=12)
        return super(Squadron, self)._create_game(**kw)

    def _start(self, **kw):
        self.s['talon'].dealRow(rows=self.s['reserves'], frames=0)
        super(Squadron, self)._start(**kw)


class LittleForty(FortyThieves):
    """
    Finish cards on _foundation_ within 4 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 open card. Build down in rank
      alone. Play seq by same suit. Gap deal 1 card from _waste_.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=4, num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: spider.SS_RK_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=115, name='Little Forty',
                    game_type=GT.FORTY_THIEVES, decks=2, redeals=3,
                    skill_level=SL.BALANCED,
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=4, num_deal=3)
    _row_ = spider.SS_RK_RowStack

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _talon_.

        *Parameters*:
           stack : Stack
             pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])

    _quickplay_ = quickplay.Spider


class Waterloo(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [6 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 1 card. Build down in rank
      alone. Play seq by same suit.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Init deal base ACE. Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: spider.SS_RK_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=540, name='Waterloo', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = spider.SS_RK_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 6)
        return super(Waterloo, self)._start(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        self.s['talon'].dealRow(rows=self.s['foundations'])
        super(Squadron, self)._start(**kw)

    _quickplay_ = quickplay.Spider


class TheSpark(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.canfield.CanfieldLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 NW, no offset]
        - waste [1 E, no offset]
        - reserve [3 vert S talon, no offset]
        - foundation [8 horz N, no offset]

    _row_
      Init deal 1 card. Build down in rank
      by same suit. Play top.

    _reserve_
      Init deal 3 card. Build none. Play top.

    _talon_
      Deal 3 card on _reserve_.

    _foundation_
      Init base KING, Build up in rank by same suit wrap. Play
      top.
    ------
    :cvar Stack _talon_: TheSpark_Talon (num_deal=3)
    :cvar Stack _foundation_: stack.SS_Foundation (base_rank=KING,
      mod=13)
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=564, name='The Spark', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_LUCK, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = CanfieldLayout.CanfieldLayout
    _talon_ = Wrap(TheSpark_Talon, num_deal=3)
    _foundation_ = Wrap(stack.SS_Foundation, base_rank=cs.KING, mod=13)
    _reserve_ = stack.OpenStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, ncols=2, reserves=2, playcards=0,
                  reserve_text=True, wastecards=0)
        return super(TheSpark, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return KING on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllKing)

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(TheSpark, self)._start(**kw)


class Interchange(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [7 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 7 alt open card. Build down in
      rank by same suit. Play seq. Base KING.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=574, name='Interchange', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(stack.SS_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        kw.setdefault('rows', 7)
        return super(Interchange, self)._create_game(**kw)

    def _start(self, rows=7, **kw):
        rows -= 1
        rows /= 2
        for flip in (True, False) * rows:
            self.s['talon'].dealRow(flip=flip, frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow()
        self.s['talon'].deal_cards()


class Unlimited(Interchange):
    """
    Finish cards on _foundation_ without limit turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [7 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 7 alt open card. Build down in
      rank by same suit. Play seq. Base KING.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=575, name='Unlimited', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=cs.INFINITE, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=cs.INFINITE)


class Breakwater(Interchange):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [7 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 7 alt open card. Build down in
      rank alone. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.RK_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=576, name='Breakwater', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.RK_RowStack


class Alternation(Interchange):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [7 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 7 alt open card. Build down in
      rank by alt color. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=631, name='Alternation', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.AC_RowStack


class TripleInterchange(Unlimited):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [9 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [12 horz NE, no offset]

    _row_
      Init deal 9 alt open card. Build down in
      rank by same suit. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=679, name='Triple Interchange',
                    game_type=GT.FORTY_THIEVES, decks=3, redeals=-1,
                    skill_level=SL.MOSTLY_SKILL, altnames=(
                    'Interchange (3 Decks)',),
                    version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.SS_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 9)
        return super(TripleInterchange, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 9)
        super(TripleInterchange, self)._start(**kw)


class Crossroads(Alternation):
    """
    Finish cards on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 7 alt open card. Build down in
      rank by alt color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 16 over 2 row N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=628, name='Crossroads', game_type=GT.FORTY_THIEVES,
                    decks=4, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=7, playcards=12, texts=True)
        return super(Crossroads, self)._create_game(**kw)


class Junction(Crossroads):
    """
    Finish cards on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 1 alt open card. Build down in
      rank by alt color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 16 over 2 row N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: gypsy.DieRussische_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=556, name='Junction', game_type=GT.FORTY_THIEVES,
                    decks=4, skill_level=SL.MOSTLY_SKILL, ranks=cs.SHORT_A7K,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _foundation_ = gypsy.DieRussische_Foundation

    def _start(self, **kw):
        kw.setdefault('rows', 1)
        super(Junction, self)._start(**kw)


class FortyNine(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [7 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 7 open card. Build down in rank
      by same suit. Play seq on gap else top on cards.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: FortyNine_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=577, name='Forty Nine', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = FortyNine_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 7)
        return super(Interchange, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 7)
        super(FortyNine, self)._start(**kw)


class Floradora(game.Game):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.klondike.KlondikeLayout
        - row [6 horz S foundation, vert offset]
        - talon [1 NW, no offset]
        - foundation [8 horz N, no offset]

    _row_
      Init deal 6 open card. Build down in rank
      by same suit. Play seq on gap else top on cards.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      N build up in rank by same suit. S _talon_ build
      in rank by same rank. S _talon_ base KING. N base ACE. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_cards=12),
      stack.RK_Foundation, base_rank=KING, dir=0, max_cards=8)
    :cvar Stack _row_: stack.RK_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=632, name='Floradora', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_LUCK, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = KlondikeLayout.KlondikeLayout
    _talon_ = stack.WasteTalon
    _waste_ = stack.WasteStack
    _foundations_ = (Wrap(stack.SS_Foundation, max_cards=12),
                     Wrap(stack.RK_Foundation, base_rank=cs.KING, dir=0,
                          max_cards=8),)
    _row_ = Wrap(stack.RK_RowStack, max_move=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        kwdefault(kw, rows=6, ncols=1, playcards=12)
        return super(Floradora, self)._create_game(**kw)

    def _start(self, rows=6, **kw):
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow()
        self.s['talon'].deal_cards()


class BlindPatience(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [10 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 4 close card. Build down in rank
      by alt color. Addition, build on close cards possible. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.

    note::
      «autoflip» disabled.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: Blind_AC_RowStack (max_move=1)
    :cvar Hint _hint_: BlindPatience_Hint
    """
    __info__ = dict(id=751, name='Blind Patience', game_type=GT.FORTY_THIEVES,
                    decks=2, skill_level=SL.MOSTLY_SKILL, version='1.10fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(Blind_AC_RowStack, max_move=1)
    _hint_ = BlindPatience_Hint

    def _start(self):
        for i in range(3):
            self.s['talon'].dealRow(flip=False, frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow(flip=False)
        self.s['talon'].deal_cards()

    def _autopiles(self, event=None):
        """
        Return piles for auto or quick move.

        Overide to disable autoflip, autodrop when not event.

        .. \_autopiles(self, event=None) -> seq(seq(Pile ...), seq(Pile ...),
             seq(Pile ...))
        """
        piles = super(BlindPatience, self)._autopiles(event)
        return autostacks.drop_quickplay(piles) if event is None else piles

    _quickplay_ = quickplay.BlindRowStack


class Foothold(FortyThieves):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation, vert offset]
        - talon [1 SW, no offset]
        - waste [1 E, horz offset]
        - foundation [8 horz NE, no offset]

    _row_
      Init deal 5 open card. Build either in rank
      by alt color. Play top.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.UD_AC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=765, name='Foothold', game_type=(GT.FORTY_THIEVES |
                    GT.ORIGINAL), decks=2, version='2.00fc',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.UD_AC_RowStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, playcards=16)
        super(TripleInterchange, self)._create_game(**kw)

    def _start(self, **kw):
        kw.setdefault('rows', 5)
        super(TripleInterchange, self)._start(**kw)

PROVIDES = [FortyThieves, BusyAces, Limited, WaningMoon, Lucas, Deuces,
            Corona, Quadrangle, Courtyard, FortyAndEight, LittleForty,
            Streets, Maria, NumberTen, RankAndFile, TripleLine, RedAndBlack,
            Zebra, Indian, Midshipman, NapoleonsExile, DoubleRail, SingleRail,
            NapoleonsSquare, Emperor, Octave, Mumbai, CarreNapoleon,
            FortunesFavor, Octagon, Squadron, Josephine, MarieRose,
            BigStreets, NumberTwelve, BigCourtyard, Express, Carnation,
            FinalBattle, SanJuanHill, Waterloo, Junction, TheSpark,
            DoubleGoldMine, Interchange, Unlimited, Breakwater, FortyNine,
            IndianPatience, Roosevelt, Crossroads, Alternation, Floradora,
            TripleInterchange, FamousFifty, BlindPatience, Foothold]